home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 04 Pathfinding and Movement / 05 Hancock / Goal_FollowLink.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-01  |  3.2 KB  |  127 lines

  1. #include "Goal_FollowLink.h"
  2.  
  3.  
  4. Goal_FollowLink::Goal_FollowLink( AI* pAI, const PathLink *pathlink)
  5.                                               : Goal( pAI ), GoalQueue(), link(pathlink),
  6.                                               linkType(Normal), active(false), jumped(false),
  7.                                               stuckTimer(0.0f)
  8. {    
  9.     //turn towards the jump first if it's a jump link
  10.     if (link->flags & PathLink::flagLinkJumpGap){
  11.         linkType = JumpOverGap;
  12.     }
  13.     else if (link->flags & PathLink::flagLinkDoor)
  14.         linkType = Door;
  15.     else if (link->Start()->flags & PathNode::flagNodeLedgeHang && link->End()->flags & PathNode::flagNodeLedgeHang){
  16.         linkType = Shimmy;
  17.     }
  18. }
  19.  
  20. Goal_FollowLink::~Goal_FollowLink()
  21. {
  22. }
  23.  
  24. bool Goal_FollowLink::Success() {
  25.     bool bDone = false;
  26.  
  27.     closeEnough = link->End()->radius; //make sure we get within the radius of the destination node
  28.  
  29.     //check if we're within the radius of the node
  30.     const Vector3& curPos = mpAI->WorldPos();
  31.     if (curPos.distance( link->End()->pos ) < closeEnough ) {
  32.         bDone = true;
  33.     }
  34.  
  35.     //make sure we're actually hanging if the nodemap says we're supposed to do a hang
  36.     //before we declare we're done
  37.     if (bDone){
  38.         //if we're supposed to be ledge-hanging
  39.         if (link->End()->flags & PathNode::flagNodeLedgeHang){
  40.             bDone = mpAI->AmILedgeHanging();
  41.         }
  42.     }
  43.  
  44.     return bDone;
  45. }
  46.  
  47. void Goal_FollowLink::DoJumpOverGap() {
  48.     Vector3 forwardDir = mpAI->ForwardDir();
  49.     const Vector3& curPos = mpAI->WorldPos();
  50.  
  51.     //make sure we're facing the right direction before we run off the cliff
  52.     float hdot = forwardDir.dot(link->End()->pos - curPos);
  53.     if (hdot > 0.8){
  54.         if (GetAtCliff()){
  55.             if (!jumped){
  56.                 mpAI->Jump();
  57.                 active->jumped = true;
  58.             }
  59.         }
  60.         mpAI->Servo(link->End()->pos, true);
  61.     }
  62.     else
  63.         mpAI->TurnTo(link->End()->pos); //make sure we're
  64. }
  65.  
  66. // Update the goal
  67. void Goal_FollowLink::Update( float secs_elapsed )
  68. {    
  69.    typeGoalStatus status = UpdateSubgoals( secs_elapsed );
  70.  
  71.    if (status==statusFailed) {
  72.         mGoalStatus = statusFailed;
  73.         return; 
  74.     }
  75.     
  76.    if (!NoSubgoals()) return;
  77.  
  78.     if (Success()) {
  79.       return; 
  80.     }
  81.  
  82.     const Vector3& curPos = mpAI->WorldPos();
  83.  
  84.     if (!active){
  85.  
  86.         mpAI->Crouch(link->End()->flags & PathNode::flagNodeCrouch);
  87.  
  88.         if (link->flags & PathLink::flagLinkJump) //clear any current motion before a jump
  89.             mpAI->DefaultStance();
  90.  
  91.         return;
  92.     }
  93.  
  94.     bool outsideDangerousLink = (link->flags & PathLink::flagLinkNearCliff && !link->InsideFatLink(curPos));
  95.  
  96.     switch(linkType){
  97.         //while following complicated link types, we want to tell the AI to not shutdown the owning state
  98.     case Door:
  99.         GoThroughDoor();
  100.         break;
  101.     case Jump:
  102.         DoJump();
  103.         break;
  104.     case JumpOverGap:
  105.         DoJumpOverGap();
  106.         break;
  107.     case Shimmy:
  108.         mpAI->DoLedgeShimmy(link->Direction());
  109.         break;
  110.     case Normal:
  111.         {
  112.             //just head towards the goal (the character may change its speed based on outsideDangerousLink)
  113.             mpAI->Servo(link->End()->pos, outsideDangerousLink);
  114.         }
  115.         break;
  116.     }
  117.     
  118.  
  119.    if (mpAI->IsStuck())
  120.         stuckTimer += secs_elapsed;
  121.     //if we're too far from the link or we've been stuck for more than a second, report a failure
  122.     if (TooFarFromLink(curPos) || (active->stuckTimer > 1.0)) {
  123.         mGoalStatus = statusFailed;
  124.         link->ReportLinkFailure();
  125.     }
  126. }
  127.